#!/usr/bin/perl
# Usage doc2jstub.pl path/to/javadoc/Class.html
# Reads the javadoc passed in as the argument and produces a java source stub (member names, method prototypes, field datatylpes, kind specifiers, inner classes, etc.)
# This file is part of Notehaus. Notehaus is released under the GPL License, version 3 or at your choice a newer one.
$/=undef;
sub doc2jstub;
sub squash_links;
sub render_symbols;
exit 1 if $ARGV[0] =~ m|(?>.*/)(.*?\.){2}|;
doc2jstub $ARGV[0], 1;
#doc2jstub "developer.android.com/reference/java/lang/String.html", 1;

sub doc2jstub {
open(FH, '<', $_[0]);
$_=<FH>;
close FH;
# modifiers, type declaration (class, interface, enum) with enclosing classes hence likened to a hierarchy shortened as h
($modifiers, $h)=/<code class="api-signature">([^<]*)(?:\s|\R)(\S+)(?:\s|\R)*<\/code>/gs;
#superclasses, superinterfaces
@h2 = (/<code class="api-signature">(.*?)<\/code>/gs); 
@h2 = @h2[1..$#h2];
$h2=join "\n", @h2;
squash_links $h2;
render_symbols $h2;
# package
while (/jd-inheritance-class-cell">/gc) {}
print "package $&;\n" if /\G.*(?=\.)/gc and $_[1];
#type parameters
/\G.*(&lt;.*)/gc;
$x= $1 =~ s/&lt;/</gr;
$x =~ s/&gt;/>/g;
eval '$h =~ s/^' . (join '\.', @hierarchy) . '\.//';
@hierarchy = (@hierarchy, $h);
print "$modifiers $h$x $h2 {\n";
# members (fields, methods, enum values, constructors...)
while(/<pre class="api-signature no-pretty-print">(.*?)<\/pre>/gs){
	$member = $1;
	squash_links $member;
 	render_symbols $member;
	print "$member;\n";
}

# inner classes
pos=0;
goto end if not /<table id="nestedclasses".*?<\/?table/gs;
my $posend=pos;
pos=$-[0];
while (/<td.*?<td.*?<code>(.*?)<\/code>/gs and $posend >= pos) {
my $f = $_[0];
my $g = $1;
my $pos = pos;
my $local_ = $_;
doc2jstub (($f=~s/(.*\/).*/\1/r). ($g=~s/.*>(.*)<.*/\1/r) . ".html", 0);
$_ = $local_;
pos = $pos;
}
end:
@hierarchy = @hierarchy[0..$#hierarchy-1];
print "}\n";
}
sub squash_links {
	$_[0] =~ s|<a href="https://developer.android.com/reference/(.*?)\.html">.*?</a>|\1|g;
	$_[0] =~ s|/|.|g;
}
sub render_symbols {
	$_[0] =~ s/&lt;/</g;
	$_[0] =~ s/&gt;/>/g;
	$_[0] =~ s/&nbsp;/ /g;
}
